﻿using System;
using System.Collections;
using System.Collections.Generic;
using AudioStudio;
using LogSystem;
using Pathfinding;
using Pathfinding.RVO;
using UnityEngine;
using UnityEngine.Serialization;
using RootMotion.Dynamics;
using Yoozoo.Core.Extensions.Engine;
using Yoozoo.Gameplay.City;
using Yoozoo.Gameplay.Liberty.Pool;
using Yoozoo.Gameplay.Liberty.StreetEvent;
using Yoozoo.Gta.Common;
using Yoozoo.Mars.Got;

namespace Yoozoo.Gameplay.Liberty.AI
{
    public class HittableTarget : MonoBehaviour
    {
        // 靶子类型
        public enum EHittableTargetType
        {
            // 固定靶
            Static = 1,
            // 移动靶
            Movable = 2,
        }
        
        // 靶子状态
        public enum EHittableTargetState
        {
            // 显示
            Show = 0,
            // 击中
            OnHit = 1,
            // 隐藏
            Hide = 2,
        }
        
        // 普通飘字资源路径
        private const string kScoreHudResPath = "Assets/ResourcesAssets/Hanging/Prefabs/Misc/rpg_street_flytext.prefab";
        // 爆头飘字资源路径
        private const string kHeadShootScoreHudResPath = "Assets/ResourcesAssets/Hanging/Prefabs/Misc/rpg_street_flytext_ishead.prefab";
        
        // 靶子命中音效
        private const string kOnHitSoundName = "sfx_battle_target_hit";
        // 靶子出现音效
        private const string kOnShowSoundName = "sfx_battle_target_appear";
        // 靶子倒地音效
        private const string kOnDownSoundName = "sfx_battle_target_down";
        // 爆头音效
        private const string kOnHeadShootSoundName = "UE_Shoot_battle_barget_headshoot";
        
        // 当前实例
        public AIEntity aiEntity;
        // 当前靶子资源路径
        [SerializeField]
        private string _resPath;
        
        // Animation
        [SerializeField]
        private Animation _animation;
        // 弹起动画
        [SerializeField]
        private string _upAnimationName;
        // 倒下动画
        [SerializeField]
        private string _downAnimationName;
        // 生命周期消失动画
        [SerializeField]
        private string _timeoutAnimationName;
        
        // 弹痕特效路径
        [SerializeField]
        private string _onHitEffectResPath;
        // 弹痕特效父节点
        [SerializeField]
        private Transform _onHitEffectParent;
        
        // 普通飘字
        private GameObject _scoreHud;
        // 爆头飘字
        private GameObject _headShootScoreHud;
        
        // 所有碰撞体
        private Collider[] _colliders;
        
        // 靶子状态
        [SerializeField]
        private EHittableTargetState _state = EHittableTargetState.Show;
        // 生命周期计时器
        private float _lifeTimeTimer;
        // 移动方向
        private int _moveDirection;
        // 移动百分比
        private float _movePercent;
        
        // 靶子所属轨道
        public int LineId => _lineId;
        private int _lineId;
        // 出生点
        public int SpawnPointIndex => _spawnPointIndex;
        private int _spawnPointIndex;
        // 靶子类型
        private EHittableTargetType _type;
        // 靶子生命周期
        private float _lifeTime;
        // 靶子速度
        private float _speed;
        // 靶子分数
        private int _score;
        // 靶子头部分数
        private int _headScore;
        // 精英靶
        private int _eliteTarget;

        private void Awake()
        {
            _colliders = gameObject.GetComponentsInChildren<Collider>();
        }

        /// <summary>
        /// 显示靶子
        /// </summary>
        public void Show(int lineId, int spawnPoint, EHittableTargetType type, string resPath, float lifeTime, float speed, int score, int head_score, int elite_target)
        {
            int spawnPointIndex = spawnPoint;
            // 设置位置
            var line = StreetEventHittableTargetManager.GetInstance().GetLine(lineId);
            transform.SetParent(line.transform);
            switch (type)
            {
                case EHittableTargetType.Static:
                    {
                        if (spawnPoint == 0)
                        {
                            // 随机位置
                            spawnPointIndex = line.RandomEmptySpawnPointIndex();
                        }
                        transform.position = line.GetSpawnPointPosition(spawnPointIndex);
                    }
                    break;

                case EHittableTargetType.Movable:
                    {
                        // 随机方向
                        _moveDirection = UnityEngine.Random.Range(0, 100) > 50 ? -1 : 1;
                        // 随机位置
                        _movePercent = UnityEngine.Random.Range(0f, 1f);
                        transform.position = line.GetPointPositionOnLine(_movePercent);
                    }
                    break;
            }
            
            _lineId = lineId;
            _spawnPointIndex = spawnPointIndex;
            _type = type;
            _resPath = resPath;
            _lifeTime = lifeTime;
            _speed = speed;
            _score = score;
            _headScore = head_score;
            _eliteTarget = elite_target;

            aiEntity.data.hp = 1;
            _state = EHittableTargetState.Show;
            _lifeTimeTimer = 0;
            _scoreHud = null;
            _headShootScoreHud = null;
            _animation.Play(_upAnimationName);
            foreach(var collider in _colliders)
            {
                collider.enabled = true;
            }
            // 出现音效
            AudioManager.PlaySound(kOnShowSoundName, gameObject);
        }

        /// <summary>
        /// 隐藏靶子
        /// </summary>
        public void Hide()
        {
            _state = EHittableTargetState.Hide;
            // 回收所有弹痕特效
            foreach (Transform child in _onHitEffectParent)
            {
                LibertyPoolMgr.GetInstance().Push(_onHitEffectResPath, child.gameObject);
            }
            // 回收飘字
            if (_scoreHud != null)
            {
                LibertyPoolMgr.GetInstance().Push(kScoreHudResPath, _scoreHud);
                _scoreHud = null;
            }
            if (_headShootScoreHud != null)
            {
                LibertyPoolMgr.GetInstance().Push(kHeadShootScoreHudResPath, _headShootScoreHud);
                _headShootScoreHud = null;
            }
            // 回收自身
            LibertyPoolMgr.GetInstance().Push(_resPath, gameObject);
            // 从轨道中移除
            if (_lineId > 0)
            {
                StreetEventHittableTargetManager.GetInstance().RemoveHittableTargetFromLine(this);
            }
        }
        
        public void OnHit(int damageHp, bool isHead)
        {
            if (_state != EHittableTargetState.Show)
            {
                return;
            }
            
            aiEntity.data.hp -= damageHp;
            _state = EHittableTargetState.OnHit;
            _animation.Play(_downAnimationName);
            foreach(var collider in _colliders)
            {
                collider.enabled = false;
            }
            Timers.inst.Add(0.3f, 1, o =>
            {
                // 倒地音效
                AudioManager.PlaySound(kOnDownSoundName, gameObject);
            });
            Timers.inst.Add(1f, 1, o =>
            {
                Hide();
            });
            
            if (_score > 0)
            {
                // 显示飘字
                LibertyPoolMgr.GetInstance().Pop(kScoreHudResPath, go =>
                {
                    _scoreHud = go;
                    go.gameObject.SetParent(transform);
                    go.transform.position = transform.position + Vector3.up*2f;
                    var streetScoreHud = go.GetComponent<StreetScoreHud>();
                    streetScoreHud.SetText($"+{_score}");
                });
                if (isHead)
                {
                    LibertyPoolMgr.GetInstance().Pop(kHeadShootScoreHudResPath, go =>
                    {
                        _headShootScoreHud = go;
                        go.gameObject.SetParent(transform);
                        go.transform.position = transform.position + Vector3.up*2f;
                        var streetScoreHud = go.GetComponent<StreetScoreHud>();
                        streetScoreHud.SetText($"+{_headScore}");
                    });
                }
                // 计分
                ResidentHandler.Inst.GetFunction("CityLuaFunction.addStreetEventScore").Action(isHead?_score+_headScore:_score);
                // 数据统计
                ResidentHandler.Inst.GetFunction("CityLuaFunction.addStreetEventShootingTargetData").Action(1, _eliteTarget==1?1:0, isHead?1:0);
            }
            
            // 击中音效
            AudioManager.PlaySound(kOnHitSoundName, gameObject);
            if (isHead)
            {
                // 爆头音效
                AudioManager.PlaySound(kOnHeadShootSoundName, gameObject);
            }
        }
        
        public void OnGunHitPoint(Vector3 position, Vector3 normal)
        {
            // 显示弹痕特效
            LibertyPoolMgr.GetInstance().Pop(_onHitEffectResPath, go =>
            {
                go.gameObject.SetParent(_onHitEffectParent);
                go.transform.position = position;
                go.transform.forward = normal;
            });
        }

        private void Update()
        {
            
            if (_state==EHittableTargetState.Show)
            {
                // 生命周期
                if (_lifeTime > 0)
                {
                    _lifeTimeTimer += Time.deltaTime;
                    if (_lifeTimeTimer >= _lifeTime)
                    {
                        _state = EHittableTargetState.OnHit;
                        _animation.Play(_timeoutAnimationName);
                        foreach(var collider in _colliders)
                        {
                            collider.enabled = false;
                        }
                        Timers.inst.Add(1f, 1, o =>
                        {
                            Hide();
                        });
                        return;
                    }
                }
                
                // 移动靶子
                if (_type == EHittableTargetType.Movable)
                {
                    var line = StreetEventHittableTargetManager.GetInstance().GetLine(_lineId);
                    float deltaPercent = _speed * Time.deltaTime / line.GetLineLength() * _moveDirection;
                    _movePercent += deltaPercent;
                    if (_movePercent >= 1)
                    {
                        _moveDirection = -1;
                        _movePercent = 1;
                    }
                    else if (_movePercent < 0)
                    {
                        _moveDirection = 1;
                        _movePercent = 0;
                    }
                    transform.position = line.GetPointPositionOnLine(_movePercent);
                }
                
            }
        }
        
        
    }
}